%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "stack.h"
#include "mm.h"
#include "read.h"
#include "error.h"

static int isempty;
static int iserror;
static void * return_list;
extern int linha;
extern int numero;
extern int s_exp;
extern FILE * yyin;
%}

%union{
	int i;
	double d;
	char *s;
	void *l;
};

%token <s> TOKEN STRING;
%token <i> INTEIRO CHAR;
%token <d> REAL;
%token NIL T EOF_F;

%type <l> Sexpr expressoes expressao

%%

programa    : expressao{return_list = $1; return 0;}
	    | EOF_F {return_list = NULL; return 1;}
            ;


Sexpr	    : '(' expressoes')' {$$=$2;}
            ;
			
expressoes  :  expressao  expressoes   {$$ = MMCons($1,$2);}
            |  expressao '.' expressao {$$ = MMCons($1,$3);}
            |                          {$$ = MMNil();}
            ;

expressao   :  TOKEN    {$$ = MMSymbolNotSeperated($1);}
     	      |  INTEIRO {$$ = MMInt($1);}
	          |  REAL    {$$ = MMDouble($1);}
            |  Sexpr   {$$ = $1;}
            |  NIL     {$$ = MMNil();}
            |  T       {$$ = MMT();}
            |  STRING  {$$ = MMString($1);}
            |  CHAR    {$$ = MMChar($1);}
            | '#' '(' expressoes ')' {$$ = MMCons(MMSymbol("makeVector", "System"),
																					 MMCons(MMSymbol("fromList", "Keyword"),
																					 MMCons($3, MMNil())));}
            
            |  '\'' TOKEN   {$$ = MMCons(MMSymbol("quote", "System"),MMCons(MMSymbol($2, NULL), MMNil()));}
            |  '\'' INTEIRO {$$ = MMCons(MMSymbol("quote", "System"),MMCons(MMInt($2), MMNil()));}
            |  '\'' REAL    {$$ = MMCons(MMSymbol("quote", "System"),MMCons(MMDouble($2),MMNil()));}
            |  '\'' Sexpr   {$$ = MMCons(MMSymbol("quote", "System"),MMCons($2,MMNil()));}
            |  '\'' NIL     {$$ = MMCons(MMSymbol("quote", "System"),MMCons(MMNil(), MMNil()));}
            |  '\'' T       {$$ = MMCons(MMSymbol("quote", "System") ,MMCons(MMT(), MMNil()));}
            |  '\'' STRING  {$$ = MMCons(MMSymbol("quote", "System") ,MMCons(MMString($2), MMNil()));}
            |  '\'' CHAR    {$$ = MMCons(MMSymbol("quote", "System") ,MMCons(MMChar($2), MMNil()));}
            
            ;
            
           
%%

void * MYread(void)
{
	for(;;)
	{
		yyparse();
		if(!return_list)
		{
			printf("; No Value\n");
			ERRORJump();
		}else
			return return_list;
	}
		
}

int yyerror(char *s)
{
	char string[1024];
	sprintf(string, "In %d of line %d: %s", currentLine(), currentNumber(), s);
	ERRORThrow(string);
	iserror = 1;
  return 1;
}

void import_file(char * file, int verbose)
{
	FILE * pipe_tmp = fopen(file, "r");
	int n;	
	PARSER * temp;
	if(!pipe_tmp)
	{
		printf("eval: error while opening file %s\n", file);
		printf("evalutaion aborted\n");
	}else{
		fclose(pipe_tmp);
		temp = switchParser(NewParser(file));
		if(verbose)
			printf("; importing file %s\n", file);	 
		n = yyparse();
		while(return_list && !n)
		{
			if(verbose)
					print(return_list);
				/*print(eval(return_list));*/
			else
			{
				/*eval(return_list);*/
				/*StackPOP();*/
			}
			n=yyparse();
		}
	}
	destroyLexical(switchParser(temp));
}
